using System;
using System.Collections.Generic;
using SimpleJSON;
using UnityEngine;

namespace Gj.LeanCloud
{
    public class Leaderboard
    {
        public static Dictionary<string, JSONArray> ListCache = new Dictionary<string, JSONArray>() {};
        public static Dictionary<string, JSONArray> HistoryCache = new Dictionary<string, JSONArray>() {};

        public static void BatchUpdate(JSONArray all, Action<bool> callback)
        {
            if (!Auth.IsLogin()) return;
            Project.ProjectUpdate.Queue.Enqueue(async () =>
            {
                try
                {
                    Debug.Log($"batch update leaderboard");
                    var header = Api.BaseHeader();
                    header["X-LC-Session"] = Auth.SessionToken;
                    var data = new JSONArray();
                    foreach (var one in all.Children)
                    {
                        var item = new JSONObject();
                        item["statisticName"] = one["identity"].Value.Replace("-", "_");
                        item["statisticValue"] = one["value"];
                        data.Add(item);
                    }
                    await Api.Post("/leaderboard/users/self/statistics", data, header);
                    callback(true);
                }
                catch (Exception e)
                {
                    callback(false);
                }
            });
        }
        public static void Update(string identity, int value, Action<bool> callback)
        {
            if (!Auth.IsLogin()) return;
            identity = identity.Replace("-", "_");
            if (ListCache.TryGetValue(identity, out var result))
            {
                // 在排行内的数据，直接删除缓存，更新排行
                if (result != null)
                {
                    Debug.LogError(result.Count+"->"+result[result.Count - 1]["score"]);
                    if (result[result.Count - 1]["score"].AsInt != value || result.Count < 100)
                    {
                        ListCache.Remove(identity);
                    }
                }
                else
                {
                    ListCache.Remove(identity);
                }
            }
            Project.ProjectUpdate.Queue.Enqueue(async () =>
            {
                try
                {
                    Debug.Log($"update leaderboard: {identity} {value}");
                    var header = Api.BaseHeader();
                    header["X-LC-Session"] = Auth.SessionToken;
                    var data = new JSONArray();
                    var item = new JSONObject();
                    item["statisticName"] = identity;
                    item["statisticValue"] = value;
                    data.Add(item);
                    await Api.Post("/leaderboard/users/self/statistics", data, header);
                    callback(true);
                }
                catch (Exception e)
                {
                    callback(false);
                }
            });
        }

        public static void Number(string identity, Action<int> callback)
        {
            if (!Auth.IsLogin()) return;
            identity = identity.Replace("-", "_");
            if (ListCache.TryGetValue(identity, out var result))
            {
                var rank = -1;
                // 有缓存直接读取缓存
                for (var i = 0; i < result.Count; i++)
                {
                    var info = result[i];
                    if (info["userId"].Value != Auth.ObjectId) continue;
                    rank = info["rank"];
                    break;
                }
                callback(rank);
            }
            // Project.ProjectUpdate.Queue.Enqueue(async () =>
            // {
            //     Debug.Log($"self leaderboard: {identity}");
            //     var data = new JSONObject();
            //     data["statistics"] = identity;
            //     var scoreResponse = await Api.Get($"/leaderboard/users/{Auth.ObjectId}/statistics", data,
            //         Api.BaseHeader());
            //     var item = scoreResponse["result"][0].AsObject;
            //     var info = new JSONObject();
            //     info["score"] = item["statisticValue"];
            //     info["rank"] = 0;
            //     callback(info);
            // });
        }

        public static void HistoryNumber(string version, string identity, Action<int> callback)
        {
            identity = identity.Replace("-", "_");
            var key = version + ":" + identity;
            if (HistoryCache.TryGetValue(key, out var result))
            {
                var rank = -1;
                // 有缓存直接读取缓存
                for (var i = 0; i < result.Count; i++)
                {
                    var info = result[i];
                    if (info["userId"].Value != Auth.ObjectId) continue;
                    rank = info["rank"];
                    break;
                }
                callback(rank);
            }
            // Project.ProjectUpdate.Queue.Enqueue(async () =>
            // {
            //     Debug.Log($"self leaderboard: {identity}");
            //     var data = new JSONObject();
            //     data["statistics"] = identity;
            //     var scoreResponse = await Api.Get($"/leaderboard/users/{Auth.ObjectId}/statistics", data,
            //         Api.BaseHeader());
            //     var item = scoreResponse["result"][0].AsObject;
            //     var info = new JSONObject();
            //     info["score"] = item["statisticValue"];
            //     info["rank"] = 0;
            //     callback(info);
            // });
        }

        public static void List(string identity, int limit, Action<JSONArray> callback)
        {
            if (!Auth.IsLogin()) return;
            identity = identity.Replace("-", "_");
            if (ListCache.TryGetValue(identity, out var result))
            {
                // 有缓存直接读取缓存
                callback(result);
                return;
            }
            Project.ProjectUpdate.Queue.Enqueue(async () =>
            {
                Debug.Log($"list leaderboard: {identity} {limit}");
                var data = new JSONObject();
                data["selectKeys"] = "nickName,avatar";
                data["includeKeys"] = "nickName,avatar";
                data["maxResultsCount"] = $"{limit}";
                data["startPosition"] = "0";
                var scorePageResponse = await Api.Get($"/leaderboard/leaderboards/user/{identity}/ranks", data, Api.BaseHeader());

                var info = new JSONArray();
                foreach (var one in scorePageResponse["results"].AsArray.Children)
                {
                    var item = new JSONObject();
                    item["score"] = one["statisticValue"];
                    item["userId"] = one["user"]["objectId"];
                    item["rank"] = one["rank"].AsInt + 1;
                    item["nickName"] = one["user"]["nickName"].IsObject ? one["user"]["nickName"]["name"] : one["user"]["nickName"];
                    info.Add(item);
                }

                ListCache[identity] = info;
                callback(info);
            });

        }

        public static void History(string version, string identity, int limit, Action<JSONArray> callback)
        {
            identity = identity.Replace("-", "_");
            var key = version + ":" + identity;
            if (HistoryCache.TryGetValue(key, out var result))
            {
                // 有缓存直接读取缓存
                callback(result);
                return;
            }
            Project.ProjectUpdate.Queue.Enqueue(async () =>
            {
                Debug.Log($"history leaderboard: {identity} {limit}");
                var data = new JSONObject();
                data["selectKeys"] = "nickName,avatar";
                data["includeKeys"] = "nickName,avatar";
                data["maxResultsCount"] = $"{limit}";
                data["startPosition"] = "0";
                var scorePageResponse = await Api.Get($"/leaderboard/leaderboards/user/{identity}/ranks", data, Api.HistoryHeader(version));

                var info = new JSONArray();
                foreach (var one in scorePageResponse["results"].AsArray.Children)
                {
                    var item = new JSONObject();
                    item["score"] = one["statisticValue"];
                    item["userId"] = one["user"]["objectId"];
                    item["rank"] = one["rank"].AsInt + 1;
                    item["nickName"] = one["user"]["nickName"].IsObject ? one["user"]["nickName"]["name"] : one["user"]["nickName"];
                    info.Add(item);
                }

                HistoryCache[key] = info;
                callback(info);
            });

        }
    }
}